#include "std.h"
#include "tcp.h"

void web_read_req(int fd, char *ptr, char *get)
{
    FILE *fr = fdopen(fd, "r");
    char line[100];
    fgets(line, 100, fr);
    sscanf(line, "%s %s", get, ptr);
}

void web_handler_return(int fd, char *content)
{
    FILE *fw = fdopen(fd, "w");
    int content_length = strlen(content);
    fprintf(fw, "HTTP/1.0 200 OK\r\n");
    fprintf(fw, "Server: tiny httpd\r\n");
    fprintf(fw, "Content-type: text/html\r\n");
    fprintf(fw, "Content-length: %d\r\n", content_length);
    fprintf(fw, "Connection: close\r\n");
    fprintf(fw, "\r\n");

    fwrite(content, content_length, 1, fw);
    fflush(fw);
}

void web_handler_file(int fd, char *path)
{
    FILE *fr = fopen(path, "r");
    fseek(fr, 0, SEEK_END);
    int size = ftell(fr);
    fseek(fr, 0, SEEK_SET);

    char *content = malloc(size + 1);
    fread(content, 1, size, fr);
    content[size] = '\0';
    fclose(fr);

    web_handler_return(fd, content);

    free(content);
}

void web_handler_dir(int fd, char *path, char *ptr)
{
    DIR *dir = opendir(path);
    struct dirent *entry;
    char content[2000] = "<html><head><title>Index of ";
    strcat(content, ptr);
    strcat(content, "</title></head><body><h1>Index of ");
    strcat(content, ptr);
    strcat(content, "</h1>");
    while (entry = readdir(dir)) {
        if (strcmp(entry->d_name, ".") == 0)
            continue;
        if (strcmp(entry->d_name, "..") == 0)
            continue;
        strcat(content, "<a href=\"");
        strcat(content, ptr);
        strcat(content, "/");
        strcat(content, entry->d_name);
        strcat(content, "\">");
        strcat(content, entry->d_name);
        strcat(content, "</a><br>");
    }
    close(dir);
    strcat(content, "<hr></body></html>");
    web_handler_return(fd, content);
}

void web_handler(int fd)
{
    char get[100];
    char ptr[100];
    web_read_req(fd, ptr, get);

    char *query_string = strchr(ptr, '?');
    if (query_string) {
        *query_string = '\0';
        query_string++;
    }
    else {
        query_string = "";
    }

    if (strstr(ptr, "/app") == NULL) {
        char path[256];
        sprintf(path, "./www%s", ptr);
        if (strchr(ptr, '.') != NULL) {
            web_handler_file(fd, path);
        }
        else {
            web_handler_dir(fd, path, ptr);
        }
    }
    else {
        if (strcmp(ptr, "/app") == 0 || strcmp(ptr, "/app/") == 0) {
            web_handler_dir(fd, "./www/app", ptr);
        }
        else {
            
        }
    }
    close(fd);
}

void *web_entry(void *arg)
{
    int fd = (long) arg;
    web_handler(fd);
    close(fd);
    return NULL;
}

void run_web_server(char *ip_addr, int port)
{
    int server_fd = tcp_listen(ip_addr, port);

    while(1) {
        int client_fd = tcp_accept(server_fd);
        if (client_fd < 0)
            fatal("accept");
        printf("accept client\n");

        pthread_t web_thread;
        //pthread_create(&web_thread, NULL, web_entry, (void *)(long)client_fd);
        web_entry((void *)(long)client_fd);
    }

    close(server_fd);
}

int main(int argc, char *argv[])
{
    char *ip_addr = "0.0.0.0";
    int port = 8080;
    run_web_server(ip_addr, port);
    return 0;
}
